package system

import (
	"fmt"
	"gitee.com/zackeus/go-zero/core/logx"
	"gitee.com/zackeus/go-zero/core/netx"
	"gitee.com/zackeus/goutil/strutil"
	"github.com/google/uuid"
	"golang.org/x/crypto/scrypt"
	"os"
	"strings"
)

const (
	envPodIp = "POD_IP"
	envPodId = "POD_ID"
)

// CurrentUser 当前用户
type CurrentUser interface {
	Id() string
	UserName() string
	Name() string
	Roles() []string
	Permissions() []string
}

// PodID 获取容器ID
func PodID() string {
	/* k8s 内部 ID */
	return os.Getenv(envPodId)
}

// IP 获取系统 IP
func IP() string {
	/* k8s 内部 IP */
	ip := os.Getenv(envPodIp)
	if strutil.IsBlank(ip) {
		ip = netx.InternalIp()
	}
	return ip
}

// Hostname 获取系统 host
func Hostname() string {
	hostname, err := os.Hostname()
	if err != nil {
		logx.Errorf("get hostname failed, err: %s", err.Error())
		return ""
	}
	return hostname
}

// UUID 生成 UUID
func UUID() (string, error) {
	s, err := uuid.NewRandom()
	if err != nil {
		return "", err
	}
	return strings.Replace(s.String(), "-", "", -1), nil
}

// PasswdEncode 密码加密
// salt: 要用于生成密钥的随机值
// pwd: 要用于生成密钥的密码
func PasswdEncode(salt, pwd string) (string, error) {
	// N：生成密钥所需的计算次数，它是一个正整数 增加N的值将增加计算密钥所需的时间，从而增加破解的难度
	// r：生成密钥时要使用的块大小。它应该是一个正整数，通常为8
	// p：生成密钥时使用的并行化因子。它应该是一个正整数，通常为1。增加p的值将增加生成密钥所需的内存，从而增加破解的难度
	// keyLen：要生成的密钥长度（以字节为单位）
	dk, err := scrypt.Key([]byte(pwd), []byte(salt), 32768, 8, 1, 32)
	if err != nil {
		return "", err
	}
	return fmt.Sprintf("%x", string(dk)), nil
}

// VerifyPasswd for quick verify input password is valid
// p: from db or config, generated by EncryptPasswd()
func VerifyPasswd(p, pwd, salt string) bool {
	pwdv, err := PasswdEncode(salt, pwd)
	if err != nil {
		return false
	}
	return strutil.IEqual(pwdv, p)
}
